#include <iostream>
#include <vector>
#include <set>
using namespace std;
/*
给定两个字符串 s 和 t 。返回 s 中包含 t 的所有字符的最短子字符串。如果 s 中不存在符合条件的子字符串，则返回空字符串 "" 。

如果 s 中存在多个符合条件的子字符串，返回任意一个。

 

注意： 对于 t 中重复字符，我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。

 

示例 1：

输入：s = "ADOBECODEBANC", t = "ABC"
输出："BANC" 
解释：最短子字符串 "BANC" 包含了字符串 t 的所有字符 'A'、'B'、'C'
示例 2：

输入：s = "a", t = "a"
输出："a"
示例 3：

输入：s = "a", t = "aa"
输出：""
解释：t 中两个字符 'a' 均应包含在 s 的子串中，因此没有符合条件的子字符串，返回空字符串。
 

提示：

1 <= s.length, t.length <= 105
s 和 t 由英文字母组成
 

进阶：你能设计一个在 o(n) 时间内解决此问题的算法吗？

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/M1oyTv
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
*/

class Solution
{
public:
    string minWindow(string s, string t)
    {
        if (s.size() < t.size())
            return "";
        if (s.size() == 1 && t.size() == 1)
            return s[0] == t[0] ? s : "";

        vector<int> count(128, 0);
        int needCount = t.size();
        for (char c : t)
        {
            count[c]++;
        }
        for (int i = 0; i < count.size(); i++)
        {
            if (count[i] == 0)
                count[i] = INT32_MIN;
        }

        int right = 0;
        int size = INT32_MAX;
        int start = 0;
        for (int left = 0; left < s.size(); left++)
        {
            while (right < s.size() && needCount > 0)
            {
                if (count[s[right]] != INT32_MIN)
                {
                    if (count[s[right]] > 0)
                        needCount--;
                    count[s[right]]--;
                }
                right++;
            }
            if (needCount == 0 && right - left < size)
            {
                size = right - left;
                start = left;
            }
            if (count[s[left]] != INT32_MIN)
            {
                if (count[s[left]] == 0)
                    needCount++;
                count[s[left]]++;
            }
        }
        return size < INT32_MAX ? s.substr(start, size) : "";
    }
};